import unittest
from BeautifulReport import BeautifulReport
import os

import unittest
import hashlib
import hmac
import json
from urllib import parse
import time
import requests

# 用例存放位置，把放用例的地址填上去填到用例的文件夹
base_dir = os.path.dirname(__file__)
test_case_path=base_dir
# 用来测试报告存放位置
report_path = base_dir
# 自定义测试报告名称
filename='report.html'
#html里面报告汇总用例的名称
description='简单测试'
# 需要执行哪些用例，如果目录下的全部，可以改为"*.py"，如果是部分带test后缀的，可以改为"*test.py"
#我这里运行全部的测试用例
pattern="testCase.py"

host = "pre-ad-data-agw.gacicv.com"

def getapiheader(URI, query, method):
    """
    通过aksk获取header
    """
    query = "&".join(sorted(query.split("&")))
    AK = "0afe4445b872404393695122bc0b30e5"
    SK = '2cb1b6b1770b40899675cbc8157b4f16'

    # 2.x-bce-date
    x_bce_date = time.gmtime()
    x_bce_date = time.strftime('%Y-%m-%dT%H:%M:%SZ', x_bce_date)
    # 3.header和signedHeaders
    header = {
        "Host": host,
        "content-type": "application/json;charset=utf-8",
        "x-bce-date": x_bce_date
    }
    signedHeaders = "content-type;host;x-bce-date"
    # 4.认证字符串前缀
    authStringPrefix = "bce-auth-v1" + "/" + AK + "/" + x_bce_date + "/" + "1800"
    # 5.生成CanonicalRequest
    # 5.1生成CanonicalURI
    CanonicalURI = parse.quote(URI)  # windows下为urllib.parse.quote，Linux下为urllib.quote
    # 5.2生成CanonicalQueryString
    CanonicalQueryString = query  # 如果您调用的接口的query比较复杂的话，需要做额外处理
    # 5.3生成CanonicalHeaders
    result = []
    for key, value in header.items():
        tempStr = str(parse.quote(key.lower(), safe="")) + ":" + str(parse.quote(value, safe=""))
        result.append(tempStr)
    result.sort()
    CanonicalHeaders = "\n".join(result)
    # 5.4拼接得到CanonicalRequest
    CanonicalRequest = method + "\n" + CanonicalURI + "\n" + CanonicalQueryString + "\n" + CanonicalHeaders
    # 6.生成signingKey
    signingKey = hmac.new(SK.encode('utf-8'), authStringPrefix.encode('utf-8'), hashlib.sha256)
    # 7.生成Signature
    Signature = hmac.new((signingKey.hexdigest()).encode('utf-8'), CanonicalRequest.encode('utf-8'),
                         hashlib.sha256)
    # 8.生成Authorization并放到header里
    header['Authorization'] = authStringPrefix + "/" + signedHeaders + "/" + Signature.hexdigest()
    return header


class MyTestCase(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.parentId = 10000235  # 场景所属根节点
        cls.sceneSetName = "apiadd0611"  # 场景集名称
        cls.params = {}  # 存储操作的场景集ID，场景ID等

    def test_case_001(self):
        """获取地图"""
        path = "/v1/map"
        url = "http://" + host + path
        payload = json.dumps({
            "mapGroupId": 80
        })

        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.status_code,response.text)
        self.assertEqual(response.status_code,response.json()["status"],msg="接口请求失败或返回码状态不为200")

    def test_case_002(self):
        """新建场景集:场景集Id给到变量self.params["groupId"]，后面case用"""
        path = "/v1/scene/ads/aggregate"
        url = "http://" + host + path
        payload = json.dumps({
            "groupId": "",
            "name": self.sceneSetName,
            "labelList": [],
            "parentId": self.parentId
        })
        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.text)
        self.params["groupId"] = response.json()["result"]
        self.assertEqual(response.status_code, response.json()["status"], msg="接口请求失败或返回码状态不为200")

    def test_case_002_sub1(self):
        """新建场景集，必填项校验: 不输入场景集name字段"""
        path = "/v1/scene/ads/aggregate"
        url = "http://" + host + path
        payload = json.dumps({
            "groupId": "",
            # "name": self.sceneSetName,
            "labelList": [],
            "parentId": self.parentId
        })
        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.text)
        self.assertEqual(response.status_code, 200, msg="接口请求失败")
        self.assertEqual(response.json()["status"], 1001, msg="响应体中状态码不应为200")

    def test_case_002_sub2(self):
        """新建场景集，必填项校验: 不输入场景集labelList字段"""
        path = "/v1/scene/ads/aggregate"
        url = "http://" + host + path
        payload = json.dumps({
            "groupId": "",
            "name": self.sceneSetName,
            # "labelList": [],
            "parentId": 10000235
        })
        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.text)
        self.assertEqual(response.status_code, 200, msg="接口请求失败")
        self.assertEqual(response.json()["status"], 1001, msg="响应体中状态码不应为200")

    def test_case_003(self):
        """获取场景集列表"""
        path = "/v1/scene/ads/group"
        query = "pageNo=1&pageSize=10"
        url = "http://" + host + path + "?" + query
        response = requests.request("GET", url, headers=getapiheader(path, query, "GET"), )
        print(response.text)
        self.assertEqual(response.status_code, response.json()["status"], msg="接口请求失败或返回码状态不为200")

    def test_case_003_sub1(self):
        """获取场景集列表,必填项校验，不输入pageNo和&pageSize"""
        path = "/v1/scene/ads/group"
        url = "http://" + host + path
        response = requests.request("GET", url, headers=getapiheader(path, "", "GET"), )
        print(response.text)
        self.assertEqual(response.status_code, 200, msg="接口请求失败")
        self.assertNotEqual(response.json()["status"], 200, msg="响应体中状态码不应为200")

    def test_case_004(self):
        """编辑场景集：场景集ID使用case2生成的"""
        path = "/v1/scene/ads/aggregate"
        url = "http://" + host + path
        payload = json.dumps({
            "groupId": self.params["groupId"],
            "parentId": self.parentId,
            "leaf": 1,
            "path": "",
            "sort": 0,
            "name": self.sceneSetName,
            "description": "用接口编辑一下场景集描述",
            "labelList": [],
        })
        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.text)
        self.assertEqual(response.status_code, response.json()["status"], msg="接口请求失败或返回码状态不为200")

    def test_case_004_sub1(self):
        """编辑场景集目录：场景集ID使用case2生成的"""
        path = "/v1/scene/ads/aggregate"
        url = "http://" + host + path
        payload = json.dumps({
            "groupId": self.params["groupId"],
            "parentId": self.parentId,
            "leaf": 0,
            "path": "",
            "sort": 0,
            "name": self.sceneSetName,
            "description": "用接口编辑一下场景集描述",
            "labelList": [],
        })
        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.text)
        self.assertEqual(response.status_code, response.json()["status"], msg="接口请求失败或返回码状态不为200")

    def test_case_004_sub2(self):
        """编辑场景集,必填字段校验：缺少name字段"""
        path = "/v1/scene/ads/aggregate"
        url = "http://" + host + path
        payload = json.dumps({
            "groupId": self.params["groupId"],
            "parentId": self.parentId,
            "leaf": 0,
            "path": "",
            "sort": 0,
            # "name": self.sceneSetName,
            "description": "用接口编辑一下场景集描述",
            "labelList": [],
        })
        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.text)
        self.assertEqual(response.status_code, 200, msg="接口请求失败")
        self.assertNotEqual(response.json()["status"], 200, msg="响应体中状态码不应为200")

    def test_case_004_sub3(self):
        """编辑场景集,必填字段校验：缺少labelList字段"""
        path = "/v1/scene/ads/aggregate"
        url = "http://" + host + path
        payload = json.dumps({
            "groupId": self.params["groupId"],
            "parentId": self.parentId,
            "leaf": 0,
            "path": "",
            "sort": 0,
            "name": self.sceneSetName,
            "description": "用接口编辑一下场景集描述",
            # "labelList": [],
        })
        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.text)
        self.assertEqual(response.status_code, 200, msg="接口请求失败")
        self.assertNotEqual(response.json()["status"], 200, msg="响应体中状态码不应为200")

    def test_case_005(self):
        """获取场景列表：场景集ID使用case2生成的"""
        path = "/v1/scene/ads/list"
        url = "http://" + host + path
        payload = json.dumps({
            "pageNo": 1,
            "pageSize": 10,
            "groupIds": [
                self.params["groupId"]
            ]
        })
        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.text)
        self.assertEqual(response.status_code, response.json()["status"], msg="接口请求失败或返回码状态不为200")

    def test_case_005_sub1(self):
        """获取场景列表,必填项校验：缺少groupIds"""
        path = "/v1/scene/ads/list"
        url = "http://" + host + path
        payload = json.dumps({
            "pageNo": 1,
            "pageSize": 10,
            # "groupIds": [
            #     self.params["groupId"]
            # ]
        })
        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.text)
        self.assertEqual(response.status_code, 200, msg="接口请求失败")
        self.assertNotEqual(response.json()["status"], 200,msg="响应体中状态码不应为200")

    def test_case_006(self):
        """场景集详情：场景集ID使用case2生成的"""
        path = "/v1/scene/ads/aggregate/detail"
        query = "groupId=%s" % self.params["groupId"]
        url = "http://" + host + path + "?" + query

        response = requests.request("GET", url,
                                    headers=getapiheader(path, query, "GET"),)
        print(response.json()["status"],response.text,)
        self.assertEqual(response.status_code, response.json()["status"], msg="接口请求失败或返回码状态不为200")

    def test_case_006_sub1(self):
        """场景集详情,必填字段校验：缺少groupId"""
        path = "/v1/scene/ads/aggregate/detail"
        url = "http://" + host + path

        response = requests.request("GET", url,
                                    headers=getapiheader(path, "", "GET"),)
        print(response.json()["status"],response.text,)
        self.assertEqual(response.status_code, 200, msg="接口请求失败")
        self.assertNotEqual(response.status_code, response.json()["status"], msg="响应体中状态码不应为200")

    def test_case_007(self):
        """新建场景：场景Id给到变量self.params["adsId"]，后面case用"""
        path = "/v1/scene/ads"
        url = "http://" + host + path
        payload = json.dumps({
            "adsUrl": "x8v-drivingcloud-xtest/scene/tadsim/xosc/31147c41-32db-4971-80d6-46cb9514639a/logscene_performance_test7749.xosc",
            "adsFileUrl": "x8v-drivingcloud-xtest/scene/tadsim/xosc/31147c41-32db-4971-80d6-46cb9514639a/",
            "labelList": [
                "illumination", "wind", "weather"
            ],
            "adsSource": 0,
            "adsName": "logscene_performance_test7749.xosc",
            "mapName": "umc_map_20220929",
            "mapVersion": "1.0",
            "adsFormat": "open_scenario-1.4",
            "groupIds": [
                self.params["groupId"]
            ]
        })
        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.text)
        self.params["adsId"] = response.json()["result"]
        self.assertEqual(response.status_code, response.json()["status"], msg="接口请求失败或返回码状态不为200")

    # def test_case_007_sub1(self):
    #     """新建场景,必填项校验：缺少adsUrl字段"""
    #     path = "/v1/scene/ads"
    #     url = "http://" + host + path
    #     payload = json.dumps({
    #         # "adsUrl": "x8v-drivingcloud-xtest/scene/tadsim/xosc/31147c41-32db-4971-80d6-46cb9514639a/logscene_performance_test7749.xosc",
    #         "adsFileUrl": "x8v-drivingcloud-xtest/scene/tadsim/xosc/31147c41-32db-4971-80d6-46cb9514639a/",
    #         "labelList": [
    #             "illumination", "wind", "weather"
    #         ],
    #         "adsSource": 0,
    #         "adsName": "logscene_performance_test7749.xosc",
    #         "mapName": "umc_map_20220929",
    #         "mapVersion": "1.0",
    #         "adsFormat": "open_scenario-1.4",
    #         "groupIds": [
    #             self.params["groupId"]
    #         ]
    #     })
    #     response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
    #     print(response.text)
    #     self.assertEqual(response.status_code, 200, msg="接口请求失败")
    #     self.assertNotEqual(response.json()["status"], 200, msg="响应体中状态码不应为200")

    def test_case_008(self):
        """获取场景详情:场景ID使用case7生成的"""
        path = "/v1/scene/ads"
        query = "adsId=%s" % self.params["adsId"]
        url = "http://" + host + path + "?" + query

        response = requests.request("GET", url,
                                    headers=getapiheader(path, query, "GET"), )
        print(response.text)
        self.assertEqual(response.status_code, response.json()["status"], msg="接口请求失败或返回码状态不为200")

    def test_case_009(self):
        """编辑场景:
            修改场景名称（加_edit）和场景标签(去掉标签)
            场景ID使用case7生成的，场景集ID使用case2生成的
        """
        path = "/v1/scene/ads"
        url = "http://" + host + path

        payload = json.dumps({
            "adsUrl": "x8v-drivingcloud-xtest/scene/tadsim/xosc/31147c41-32db-4971-80d6-46cb9514639a/logscene_performance_test7749.xosc",
            "adsFileUrl": "x8v-drivingcloud-xtest/scene/tadsim/xosc/31147c41-32db-4971-80d6-46cb9514639a/",
            "labelList": [
                "illumination", "wind"
            ],
            "adsSource": 0,
            "adsName": "logscene_performance_test7749_edit.xosc",
            "mapName": "umc_map_20220929",
            "mapVersion": "1.0",
            "adsFormat": "open_scenario-1.4",
            "adsId": self.params["adsId"],  # 存在此字段为编辑，不存在为新增
            "groupIds": [
                self.params["groupId"]
            ]
        })
        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.text)
        self.assertEqual(response.status_code, response.json()["status"], msg="接口请求失败或返回码状态不为200")

    def test_case_010(self):
        """批量新增场景：场景集ID使用case2生成的"""
        path = "/v1/scene/batch/ads"
        url = "http://" + host + path
        payload = json.dumps({
            "adsInfoList": [
                {
                    "adsUrl": "x8v-drivingcloud-xtest/scene/tadsim/xosc/31147c41-32db-4971-80d6-46cb9514639a/logscene_performance_test7749.xosc",
                    "adsFileUrl": "x8v-drivingcloud-xtest/scene/tadsim/xosc/31147c41-32db-4971-80d6-46cb9514639a/",
                    "labelList": [
                        "illumination", "wind", "weather"
                    ],
                    "adsSource": 0,
                    "adsName": "logscene_performance_test7749.xosc",
                    "mapName": "umc_map_20220929",
                    "mapVersion": "1.0",
                    "adsFormat": "open_scenario-1.4"
                },
                {
                    "adsUrl": "x8v-drivingcloud-xtest/scene/tadsim/xosc/31147c41-32db-4971-80d6-46cb9514639a/logscene_performance_test7749.xosc",
                    "adsFileUrl": "x8v-drivingcloud-xtest/scene/tadsim/xosc/31147c41-32db-4971-80d6-46cb9514639a/",
                    "labelList": [
                        "illumination", "wind", "weather"
                    ],
                    "adsSource": 0,
                    "adsName": "logscene_performance_test7749.xosc",
                    "mapName": "umc_map_20220929",
                    "mapVersion": "1.0",
                    "adsFormat": "open_scenario-1.4"
                },
                {
                    "adsUrl": "x8v-drivingcloud-xtest/scene/tadsim/xosc/31147c41-32db-4971-80d6-46cb9514639a/logscene_performance_test7749.xosc",
                    "adsFileUrl": "x8v-drivingcloud-xtest/scene/tadsim/xosc/31147c41-32db-4971-80d6-46cb9514639a/",
                    "labelList": [
                        "illumination", "wind", "weather"
                    ],
                    "adsSource": 0,
                    "adsName": "logscene_performance_test7749.xosc",
                    "mapName": "umc_map_20220929",
                    "mapVersion": "1.0",
                    "adsFormat": "open_scenario-1.4"
                },
                {
                    "adsUrl": "x8v-drivingcloud-xtest/scene/tadsim/xosc/31147c41-32db-4971-80d6-46cb9514639a/logscene_performance_test7749.xosc",
                    "adsFileUrl": "x8v-drivingcloud-xtest/scene/tadsim/xosc/31147c41-32db-4971-80d6-46cb9514639a/",
                    "labelList": [
                        "illumination", "wind", "weather"
                    ],
                    "adsSource": 0,
                    "adsName": "logscene_performance_test7749.xosc",
                    "mapName": "umc_map_20220929",
                    "mapVersion": "1.0",
                    "adsFormat": "open_scenario-1.4"
                },
                {
                    "adsUrl": "x8v-drivingcloud-xtest/scene/tadsim/xosc/31147c41-32db-4971-80d6-46cb9514639a/logscene_performance_test7749.xosc",
                    "adsFileUrl": "x8v-drivingcloud-xtest/scene/tadsim/xosc/31147c41-32db-4971-80d6-46cb9514639a/",
                    "labelList": [
                        "illumination", "wind", "weather"
                    ],
                    "adsSource": 0,
                    "adsName": "logscene_performance_test7749.xosc",
                    "mapName": "umc_map_20220929",
                    "mapVersion": "1.0",
                    "adsFormat": "open_scenario-1.4"
                }
            ],
            "groupIds": [
                self.params["groupId"]
            ]
        })
        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.text)
        self.assertEqual(response.status_code, response.json()["status"], msg="接口请求失败或返回码状态不为200")

    def test_case_011(self):
        """
            场景集标签修改：标签修改为interface_auto
            场景集ID使用case2生成的
        """
        path = "/v1/scene/ads/aggregate/label"
        url = "http://" + host + path

        payload = json.dumps({
            "groupId": [self.params["groupId"]],
            "labelList": ["interface_auto"]
        })
        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.text)
        self.assertEqual(response.status_code, response.json()["status"], msg="接口请求失败或返回码状态不为200")

    def test_case_012(self):
        """
            场景标签修改：标签修改为空
            场景ID使用case7生成的
        """
        path = "/v1/scene/ads/label"
        url = "http://" + host + path

        payload = json.dumps({
            "adsIds": [self.params["adsId"]],
            "labelList": [],
            # "labelList": ["illumination", "wind", "weather"]
        })
        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.text)
        self.assertEqual(response.status_code, response.json()["status"], msg="接口请求失败或返回码状态不为200")

    def test_case_013(self):
        """场景文件地址获取:场景ID使用case7生成的"""
        path = "/v1/scene/ads/path"
        url = "http://" + host + path

        payload = json.dumps({
            "adsIdList": [
                1604270832
            ]
        })
        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.text)
        self.assertEqual(response.status_code, response.json()["status"], msg="接口请求失败或返回码状态不为200")

    def test_case_014(self):
        """批量新增场景集"""
        path = "/v1/scene/batch/ads/aggreage"
        url = "http://" + host + path

        payload = json.dumps({
            "aggregateList": [
                {
                    "name": "批量新增测试",
                    "description": "",
                    "labelList": [],
                    "leaf": 0,
                    "parentId": self.parentId,
                    "path": "批量新增测试",
                    "children": [
                        {
                            "name": "一级目录",
                            "leaf": 0,
                            "path": "批量新增测试-一级目录",
                            "children": [
                                {
                                    "name": "二级场景集1",
                                    "leaf": 1,
                                    "description": "测试",
                                    "labelList": [],
                                    "path": "批量新增测试-一级目录-二级场景集1"
                                },
                                {
                                    "name": "二级场景集2",
                                    "leaf": 1,
                                    "description": "测试",
                                    "labelList": [],
                                    "path": "批量新增测试-一级目录-二级场景集2"
                                }
                            ]
                        }
                    ]
                }

            ]
        })
        response = requests.request("POST", url, headers=getapiheader(path, "", "POST"), data=payload)
        print(response.text)
        self.assertEqual(response.status_code, response.json()["status"], msg="接口请求失败或返回码状态不为200")


    def test_case_099(self):
        """删除场景:场景ID使用case7生成的，关联的场景集ID为case2生成的"""
        path = "/v1/scene/ads"
        url = "http://" + host + path

        payload = json.dumps({
            "adsIds": [
                self.params["adsId"]
            ],
            "groupId": self.params["groupId"]
        })
        response = requests.request("DELETE", url, headers=getapiheader(path, "", "DELETE"), data=payload)
        print(response.text)
        time.sleep(1)
        self.assertEqual(response.status_code, response.json()["status"], msg="接口请求失败或返回码状态不为200")

    def test_case_100(self):
        """删除场景集:场景集ID为case2生成"""
        path = "/v1/scene/ads/aggregate"
        url = "http://" + host + path
        payload = json.dumps({
            "groupId": self.params["groupId"],
        })
        response = requests.request("DELETE", url, headers=getapiheader(path, "", "DELETE"), data=payload)
        print(response.text)
        self.assertEqual(response.status_code, response.json()["status"], msg="接口请求失败或返回码状态不为200")

if __name__ == '__main__':
    test_suite = unittest.defaultTestLoader.discover(test_case_path, pattern=pattern)
    #unittest的一个方法，智能获取文件下面的case去跑
    result = BeautifulReport(test_suite)
   #只能绘制图表
    result.report()
    #写入文件保存